package cn.ilikes.tools.nosql.jpa.persistences;

import java.io.File;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.persistence.EntityManager;

import org.slf4j.Logger;

import cn.ilikes.tools.logs.Loggerfactory;
import cn.ilikes.tools.nosql.jpa.JPASQLPersistenUnitEnv;
import cn.ilikes.tools.nosql.jpa.JPASQLRunTimeException;
import cn.ilikes.tools.nosql.jpa.classloads.JPASQLClassLoader;
import cn.ilikes.tools.nosql.jpa.classloads.LoadResources;
import cn.ilikes.tools.nosql.jpa.classloads.URLPathFilterLoadResources;
import cn.ilikes.tools.nosql.jpa.clients.AbClient;
import cn.ilikes.tools.nosql.jpa.clients.ClientFactory;
import cn.ilikes.tools.nosql.jpa.clients.DefultClientFactory;
import cn.ilikes.tools.nosql.jpa.clients.JPASQLClientsException;
import cn.ilikes.tools.nosql.jpa.metadatas.IEntityMetaDataFactory;

public class DefaultJPASQLEntityManagerFactory extends JPASQLEntityManagerFactory {

	private static Logger logger = Loggerfactory.instance(DefaultJPASQLEntityManagerFactory.class);

	private ClientFactory clientFactory;

	public DefaultJPASQLEntityManagerFactory(Properties envProperties, JPASQLPersistenUnitEnv persistenUnitEnv) {
		super(envProperties, persistenUnitEnv);

	}

	@Override
	public void init() {
		Loggerfactory.info(logger, "start  create  persistence units name : " + persistenUnitEnv.getPersistenUnitName() + "  JPA NOSQL Entity Manager Factory ");
		JPASQLPersistenUnitEnv persistenUnitEnv = getPersistenUnitEnv();
		createIEntityMetaDataFactory(persistenUnitEnv);
		initClientFactory(persistenUnitEnv);
		Loggerfactory.info(logger, "create  persistence units name : " + persistenUnitEnv.getPersistenUnitName() + "  JPA NOSQL Entity Manager Factory  Success ! ");

	}

	@Override
	public void close() {
		Loggerfactory.info(logger, "start  close  persistence units name : " + persistenUnitEnv.getPersistenUnitName() + "  JPA NOSQL Entity Manager Factory ");
		clientFactory.close();
		Loggerfactory.info(logger, " close  persistence units name : " + persistenUnitEnv.getPersistenUnitName() + "  JPA NOSQL Entity Manager Factory  success ");
	}

	@Override
	public boolean isOpen() {
		return clientFactory.isOpen();
	}

	@Override
	public EntityManager createEntityManager() {
		return createEntityManager(new HashMap());

	}

	@Override
	public EntityManager createEntityManager(Map arg0) {
		try {
			if (Loggerfactory.isdebug(logger))
				Loggerfactory.debug(logger, "createEntity  manager");
			JPASQLPersistenUnitEnv persistenUnitEnv = getPersistenUnitEnv();
			AbClient clients = clientFactory.createClient();
			EntityManager entityManager = new JPASQLEntityManager(persistenUnitEnv, clients, arg0);
			return entityManager;
		} catch (JPASQLClientsException e) {
			Loggerfactory.error(logger, e.getMessage());
			throw new JPASQLRunTimeException(e);
		}

	}

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	private void initClientFactory(JPASQLPersistenUnitEnv persistenUnitEnv) {
		Loggerfactory.info(logger, "start  create  persistence units name : " + persistenUnitEnv.getPersistenUnitName() + "  JPA Client  Factory ");
		ClientFactory clientFactory = new DefultClientFactory(persistenUnitEnv);
		clientFactory.init();
		setClientFactory(clientFactory);

	}

	private void createIEntityMetaDataFactory(JPASQLPersistenUnitEnv persistenUnitEnv) {
		//Loggerfactory.info(logger, "Start  Create " + persistenUnitEnv.getPersistenUnitName() + " Default  JPASQL  Entity  Manager  Factory  ! ");
		JPASQLClassLoader hbaseClassLoader = persistenUnitEnv.getPersistenUnitClassLoader();
		IEntityMetaDataFactory metaDataManagerFactory = persistenUnitEnv.getMetaDataManagerFactory();
		LoadResources loadResources = createLoadResources(hbaseClassLoader, metaDataManagerFactory);
		String classPaths_ = (String) System.getProperties().get("java.class.path");
		String[] classPaths = classPaths_.split(":");
		for (String classPath : classPaths) {
			try {
				//				if (Loggerfactory.isdebug(logger))Loggerfactory.info(logger, "start load  JPA Hbase System   lib : " + classPath);
				loadResources.loadResource(new File(classPath).toURI().toURL());
			} catch (MalformedURLException e) {
				Loggerfactory.error(logger, e);
				throw new JPASQLRunTimeException(e);
			}
		}
	}

	private LoadResources createLoadResources(final JPASQLClassLoader hbaseClassLoader, final IEntityMetaDataFactory metaDataManagerFactory) {
		LoadResources loadResources = new URLPathFilterLoadResources(new ClassFilterImpl(getPersistenUnitEnv()));
		return loadResources;
	}

	private void setClientFactory(ClientFactory clientFactory) {
		this.clientFactory = clientFactory;
	}

}
